﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management;
using System.Text;
using WMI.NET.Abstracts;
using WMI.NET.CIM;

namespace WMI.NET.ComputerSystemHardware.VideoAndMonitor
{
    /// <summary>
    /// The Win32_VideoController WMI class represents the capabilities and management capacity of the video controller on a computer system running Windows. Starting with Windows Vista, properties of this class replace Win32_DisplayConfiguration.
    /// Starting with Windows Vista, hardware that is not compatible with Windows Display Driver Model (WDDM) returns inaccurate property values for instances of this class.
    /// Windows Server 2003 and Windows XP:  This class is supported.
    /// </summary>
    public class Win32_VideoController : CIM_PCVideoController
    {

        private string _AdapterCompatibility;
        private string _AdapterDACType;
        private Nullable<UInt32> _AdapterRAM;
        private Nullable<UInt32> _ColorTableEntries;
        private Nullable<UInt32> _DeviceSpecificPens;
        private Nullable<UInt32> _DitherType;
        private Nullable<DateTimeOffset> _DriverDate;
        private string _DriverVersion;
        private Nullable<UInt32> _ICMIntent;
        private Nullable<UInt32> _ICMMethod;
        private string _InfFilename;
        private string _InfSection;
        private string _InstalledDisplayDrivers;
        private Nullable<Boolean> _Monochrome;
        private Nullable<UInt32> _ReservedSystemPaletteEntries;
        private Nullable<UInt32> _SpecificationVersion;
        private Nullable<UInt32> _SystemPaletteEntries;
        private string _VideoModeDescription;

        /// <summary>
        /// General chipset used for this controller to compare compatibilities with the system.
        /// </summary>
        public string AdapterCompatibility { get { return _AdapterCompatibility; } }

        /// <summary>
        /// Name or identifier of the digital-to-analog converter (DAC) chip. The character set of this property is alphanumeric.
        /// </summary>
        public string AdapterDACType { get { return _AdapterDACType; } }

        /// <summary>
        /// Memory size of the video adapter.(Bytes) 
        /// Example: 64000
        /// </summary>
        public Nullable<UInt32> AdapterRAM { get { return _AdapterRAM; } }

        /// <summary>
        /// Size of the system's color table. The device must have a color depth of no more than 8 bits per pixel; otherwise, this property is not set.
        /// Example: 256
        /// </summary>
        public Nullable<UInt32> ColorTableEntries { get { return _ColorTableEntries; } }

        /// <summary>
        /// Current number of device-specific pens. A value of 0xffff means that the device does not support pens.
        /// Example: 3
        /// </summary>
        public Nullable<UInt32> DeviceSpecificPens { get { return _DeviceSpecificPens; } }

        /// <summary>
        /// Dither type of the video controller. The property can be one of the predefined values, or a driver-defined value greater than or equal to 256. If line art dithering is chosen, the controller uses a dithering method that produces well-defined borders between black, white, and gray scalings. Line art dithering is not suitable for images that include continuous graduations in intensity and hue such as scanned photographs.
        /// </summary>
        public Nullable<UInt32> DitherType { get { return _DitherType; } } //TODO enum

        /// <summary>
        /// Last modification date and time of the currently installed video driver.
        /// </summary>
        public Nullable<DateTimeOffset> DriverDate { get { return _DriverDate; } }

        /// <summary>
        /// Version number of the video driver.
        /// </summary>
        public string DriverVersion { get { return _DriverVersion; } }

        /// <summary>
        /// Specific value of one of the three possible color-matching methods or intents that should be used by default. This property is used primarily for non-ICM applications. ICM applications establish intents by using the ICM functions. This property can be a predefined value or a driver defined value greater than or equal to 256. Color matching based on saturation is the most appropriate choice for business graphs when dithering is not desired. Color matching based on contrast is the most appropriate choice for scanned or photographic images when dithering is desired. Color matching optimized to match the exact color requested is most appropriate for use with business logos or other images when an exact color match is desired.
        /// </summary>
        public Nullable<UInt32> ICMIntent { get { return _ICMIntent; } } //TODO enum

        /// <summary>
        /// Method of handling ICM. For non-ICM applications, this property determines if ICM is enabled. For ICM applications, the system examines this property to determine how to handle ICM support. This property can be a predefined value or a driver-defined value greater than or equal to 256. The value determines which system handles image color matching.
        /// </summary>
        public Nullable<UInt32> ICMMethod { get { return _ICMMethod; } } //TODO enum

        /// <summary>
        /// Path to the video adapter's .inf file.
        /// Example: "C:\WINNT\SYSTEM32\DRIVERS"
        /// </summary>
        public string InfFilename { get { return _InfFilename; } }

        /// <summary>
        /// Section of the .inf file where the Windows video information resides.
        /// </summary>
        public string InfSection { get { return _InfSection; } }

        /// <summary>
        /// Name of the installed display device driver.
        /// </summary>
        public string InstalledDisplayDrivers { get { return _InstalledDisplayDrivers; } }

        /// <summary>
        /// If TRUE, gray scale is used to display images.
        /// </summary>
        public Nullable<Boolean> Monochrome { get { return _Monochrome; } }

        /// <summary>
        /// Number of reserved entries in the system palette. The operating system may reserve entries to support standard colors for task bars and other desktop display items. This index is valid only if the device driver sets the RC_PALETTE bit in the RASTERCAPS index, and is available only if the driver is compatible with 16-bit Windows. If the system is not using a palette, ReservedSystemPaletteEntries is not set.
        /// Example: 20
        /// </summary>
        public Nullable<UInt32> ReservedSystemPaletteEntries { get { return _ReservedSystemPaletteEntries; } }

        /// <summary>
        /// Version number of the initialization data specification (upon which the structure is based).
        /// </summary>
        public Nullable<UInt32> SpecificationVersion { get { return _SpecificationVersion; } }

        /// <summary>
        /// Current number of color index entries in the system palette. This index is valid only if the device driver sets the RC_PALETTE bit in the RASTERCAPS index, and is available only if the driver is compatible with 16-bit Windows. If the system is not using a palette, SystemPaletteEntries is not set.
        /// Example: 20
        /// </summary>
        public Nullable<UInt32> SystemPaletteEntries { get { return _SystemPaletteEntries; } }

        /// <summary>
        /// Current resolution, color, and scan mode settings of the video controller.
        /// Example: "1024 x 768 x 256 colors"
        /// </summary>
        public string VideoModeDescription { get { return _VideoModeDescription; } }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="mbo"></param>
        public Win32_VideoController(ManagementBaseObject mbo)
            : base(mbo)
        {
            _AdapterCompatibility = mbo.GetStringValue("AdapterCompatibility");
            _AdapterDACType = mbo.GetStringValue("AdapterDACType");
            _AdapterRAM = mbo.GetUIntValue("AdapterRAM");
            _ColorTableEntries = mbo.GetUIntValue("ColorTableEntries");
            _DeviceSpecificPens = mbo.GetUIntValue("DeviceSpecificPens");
            _DitherType = mbo.GetUIntValue("DitherType");
            _DriverDate = mbo.GetDateTimeOffsetValue("DriverDate", Consts.DateTimeFormat);
            _DriverVersion = mbo.GetStringValue("DriverVersion");
            _ICMIntent = mbo.GetUIntValue("ICMIntent");
            _ICMMethod = mbo.GetUIntValue("ICMMethod");
            _InfFilename = mbo.GetStringValue("InfFilename");
            _InfSection = mbo.GetStringValue("InfSection");
            _InstalledDisplayDrivers = mbo.GetStringValue("InstalledDisplayDrivers");
            _Monochrome = mbo.GetBoolValue("Monochrome");
            _ReservedSystemPaletteEntries = mbo.GetUIntValue("ReservedSystemPaletteEntries");
            _SpecificationVersion = mbo.GetUIntValue("SpecificationVersion");
            _SystemPaletteEntries = mbo.GetUIntValue("SystemPaletteEntries");
            _VideoModeDescription = mbo.GetStringValue("VideoModeDescription");
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public class GetWin32_VideoControllers : Win32Collection<Win32_VideoController>
    {

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override ReadOnlyCollection<Win32_VideoController> GetCollection()
        {
            List<Win32_VideoController> tempCollection = new List<Win32_VideoController>();

            foreach (var s in searcher.Get())
            {
                Win32_VideoController tempListItem = new Win32_VideoController(s);
                tempCollection.Add(tempListItem);
            }

            return tempCollection.AsReadOnly();
        }

        /// <summary>
        /// 
        /// </summary>
        public GetWin32_VideoControllers() : base("SELECT * FROM Win32_VideoController") { }

    }

}
